<template>
  <Teleport to="body">
    <div class="fixed w-96" :class="position">
      <TransitionGroup
        tag="div"
        enter-from-class="opacity-0"
        enter-to-class="opacity-100"
        enter-active-class="transition duration-1000 ease-in"
        leave-from-class="opacity-100"
        leave-to-class="opacity-0"
        leave-active-class="transition duration-500 ease-in"
      >
        <ZNotice
          v-for="notice in notices"
          v-bind="notice"
          :key="notice.name"
          @close="onClose"
        />
      </TransitionGroup>
    </div>
  </Teleport>
  <slot></slot>
</template>
<script setup lang="ts">
import { NoticeType, notificationInjectKey } from "./types";

const props = withDefaults(
  defineProps<{
    position?: string;
    duration?: number;
  }>(),
  { position: "top-4 right-4", duration: 2500 },
);

interface Notice {
  type: NoticeType;
  name: string;
  title: string;
  message: string;
  duration?: number;
}
const notices = ref<Notice[]>([]);
let id = 0;
const createNotice =
  (type: NoticeType, defaultTitle: string) =>
  (message: string, option: { title?: string; duration?: number } = {}) =>
    notices.value.push({
      type,
      name: `z-notice-${id++}`,
      title: option.title ?? defaultTitle,
      message,
      duration: option.duration ?? props.duration,
    });

const onClose = (name: string | undefined) => {
  notices.value = notices.value.filter((n) => n.name != name);
};

provide(notificationInjectKey, {
  info: createNotice("info", "info"),
  success: createNotice("success", "success"),
  warning: createNotice("warning", "warning"),
  error: createNotice("error", "error"),
});
</script>
